<template>
    <div class="page_root" :key="queryUpdateFlag" data-page-name="定期定价优化" data-page-identification="u_sfffzudxlz">
        <a-spin :spinning="pageLoading.loading" :tip="pageLoading.tip">
            <!-- begin vid_xjg6gqqxpp 自定义模板_h1df8suis4 -->
            <div class="page-container">
                <div class="toolbar">
                    <div>
                        <a-button
                            type="primary"
                            size="small"
                            class="save-btn"
                            @click="showSimulateModal"
                            style="margin-right: 16px"
                            >模拟优化</a-button
                        >
                        <a-cascader
                            v-model:value="area"
                            allow-clear
                            changeOnSelect
                            :options="treeData"
                            :fieldNames="{ children: 'districts', label: 'name', value: 'adcode' }"
                            style="width: 20em"
                            @change="handleAreaSelected"
                        />
                    </div>
                    <div style="display: flex; flex-direction: row; align-items: center">
                        <div style="display: flex; flex-direction: row; padding: 0 16px; gap: 8px">
                            <span style="display: inline-block">3D</span
                            ><a-switch v-model:checked="enableMap3D" @change="changeMap3D" />
                        </div>
                        <a-dropdown :trigger="['click']">
                            <template #overlay>
                                <div
                                    style="
                                        background-color: #fff;
                                        display: flex;
                                        flex-direction: column;
                                        gap: 8px;
                                        padding: 8px 0;
                                    "
                                >
                                    <a-checkbox v-show="showProvince" style="margin-left: 8px"
                                        >省级平均到位价</a-checkbox
                                    >
                                    <a-checkbox v-show="showProvince">市占率</a-checkbox>
                                    <a-checkbox
                                        v-show="showCity || showCountry"
                                        v-model:checked="layersConfig.enableEnterpriceLogo"
                                        >企业Logo</a-checkbox
                                    >
                                    <a-checkbox
                                        v-show="showCity || showCountry"
                                        v-model:checked="layersConfig.enableEnterpriceName"
                                        >企业名称</a-checkbox
                                    >
                                    <a-checkbox
                                        v-show="showCity || showCountry"
                                        v-model:checked="layersConfig.enableEnterpriceCapacity"
                                        >企业产能</a-checkbox
                                    >
                                    <a-checkbox
                                        v-show="showCity"
                                        v-model:checked="layersConfig.enableCityRequireAndInventory"
                                        >地级市需求&amp;熟料库存</a-checkbox
                                    >
                                    <a-checkbox v-show="showCity || showCountry">市占率</a-checkbox>
                                    <a-checkbox v-show="showCity || showCountry">监测预警</a-checkbox>
                                </div>
                            </template>
                            <a-button type="text">
                                显示图层
                                <DownOutlined />
                            </a-button>
                        </a-dropdown>
                        <a-dropdown :trigger="['click']">
                            <template #overlay>
                                <div
                                    style="
                                        background-color: #fff;
                                        display: flex;
                                        flex-direction: column;
                                        gap: 8px;
                                        padding: 8px 0;
                                    "
                                >
                                    <a-radio-group v-model:value="config.cementType">
                                        <a-radio
                                            v-for="item in cementType"
                                            :value="item"
                                            :style="{
                                                display: 'flex',
                                                height: '30px',
                                                lineHeight: '30px',
                                                paddingLeft: '8px'
                                            }"
                                            >{{ item }}</a-radio
                                        >
                                    </a-radio-group>
                                    <a-divider style="margin: 0" />
                                    <div style="display: flex; flex-direction: row">
                                        <a-checkbox-group v-model:value="config.packageType">
                                            <a-checkbox
                                                v-for="item in packageType"
                                                :value="item"
                                                style="flex: 1; margin-left: 8px"
                                                >{{ item }}</a-checkbox
                                            >
                                        </a-checkbox-group>
                                    </div>
                                </div>
                            </template>
                            <a-button type="text">
                                水泥品种
                                <DownOutlined />
                            </a-button>
                        </a-dropdown>
                    </div>
                </div>
                <div id="MapContainer" class="map-container"> </div>
            </div>
            <a-drawer
                :title="showAreaInfoName"
                placement="right"
                :closable="true"
                :visible="drawerVisible"
                :width="800"
                :mask="false"
                :body-style="{ paddingTop: 0 }"
                @close="onClose"
            >
                <a-tabs>
                    <a-tab-pane key="1" tab="区域概况">
                        <div>
                            <a-radio-group v-model:value="areaInfoType" @change="reloadAreaInfo">
                                <template v-for="type in cementType">
                                    <template v-for="pkgType in packageType">
                                        <a-radio-button :value="type + '_' + pkgType"
                                            >{{ type }}{{ pkgType }}</a-radio-button
                                        >
                                    </template>
                                </template>
                            </a-radio-group>
                        </div>
                        <a-table
                            :columns="areaInfoTableColumns"
                            :data-source="areaInfoTableData"
                            :loading="areaInfoTableLoading"
                            size="small"
                            :pagination="false"
                            bordered
                        >
                            <template #bodyCell="{ record, index, column, text }">
                                <template v-if="column.dataIndex === 'currentPrice'">
                                    <a-input
                                        v-if="record.editing && record.enterpriseType !== 'OWN'"
                                        v-model:value="record.currentPrice"
                                    />
                                    <span v-else>{{ text }}</span>
                                    <span v-if="record.priceArrow === 'UP'" style="color: red"
                                        ><arrow-up-outlined
                                    /></span>
                                    <span v-else-if="record.priceArrow === 'DOWN'" style="color: red"
                                        ><arrow-down-outlined
                                    /></span>
                                </template>
                                <template v-if="column.dataIndex === 'operate'">
                                    <a-button type="link" v-if="!record.editing" @click="record.editing = true"
                                        >编辑</a-button
                                    >
                                    <a-button
                                        type="link"
                                        v-else
                                        @click="
                                            () => {
                                                if (record.originCurrentPrice !== record.currentPrice) {
                                                    // 加个发生了变动
                                                    updateAreaInfo(record)
                                                } else {
                                                    record.editing = false
                                                }
                                            }
                                        "
                                        >保存</a-button
                                    >
                                </template>
                            </template>
                        </a-table>
                    </a-tab-pane>
                    <a-tab-pane key="2" tab="临近区县价差分析">
                        <div>
                            <a-radio-group v-model:value="areaInfoPriceDiffType">
                                <template v-for="type in cementType">
                                    <a-radio-button :value="type">{{ type }}</a-radio-button>
                                </template>
                            </a-radio-group>
                            <div>
                                <div>当前价格: </div>
                                <div
                                    v-for="item in areaInfoPriceDiffData"
                                    class="price-diff-box"
                                    style="
                                        display: flex;
                                        flex-direction: row;
                                        background: rgba(233, 243, 255, 1);
                                        height: 48px;
                                        font-size: 16px;
                                        align-items: center;
                                        padding: 0 24px;
                                    "
                                >
                                    <span
                                        style="
                                            display: inline-block;
                                            width: 8em;
                                            flex-shrink: 0;
                                            border-right: 1px solid blue;
                                            padding-right: 16px;
                                        "
                                        >{{ item.areaName }}</span
                                    >
                                    <span style="padding-left: 16px; flex: 1"
                                        >平均价差:
                                        <strong v-if="isNaN(parseFloat(item.diffPriceList[1]))">--</strong>
                                        <strong v-else-if="item.diffPriceList[1] > 0" style="color: red">{{
                                            item.diffPriceList[1]
                                        }}</strong>
                                        <strong v-else-if="item.diffPriceList[1] < 0" style="color: darkgreen">{{
                                            item.diffPriceList[1]
                                        }}</strong>
                                        <strong v-else>{{ item.diffPriceList[1] }}</strong>
                                        元
                                    </span>
                                    <span style="flex: 1"
                                        >当前价差:
                                        <strong v-if="isNaN(parseFloat(item.diffPriceList[0]))">--</strong>
                                        <strong v-else-if="item.diffPriceList[0] > 0" style="color: red">{{
                                            item.diffPriceList[0]
                                        }}</strong>
                                        <strong v-else-if="item.diffPriceList[0] < 0" style="color: darkgreen">{{
                                            item.diffPriceList[0]
                                        }}</strong>
                                        <strong v-else>{{ item.diffPriceList[0] }}</strong>
                                        元
                                    </span>
                                </div>
                            </div>
                        </div>
                    </a-tab-pane>
                    <a-tab-pane key="3" tab="定价模拟信息">
                        <!--                    <a-table :columns="pricingSimulationTableColumns" :data-source="pricingSimulationTableData" :loading="pricingSimulationTableLoading" size="small" :pagination="false" bordered>-->
                        <!--                        <template #bodyCell="{record,index, column, text}">-->
                        <!--                        </template>-->
                        <!--                    </a-table>-->
                    </a-tab-pane>
                </a-tabs>
            </a-drawer>

            <a-modal
                v-model:visible="simulateModalVisible"
                title="动态定价模拟"
                :width="1465"
                :body-style="{ maxHeight: '600px' }"
            >
                <div style="height: 552px; display: flex; flex-direction: column">
                    <a-steps v-model:current="simulateStep" size="small" @change="handleSimulateStepChange">
                        <a-step title="基本信息" />
                        <a-step title="需求与库存预测" />
                        <a-step title="方案优化" />
                    </a-steps>
                    <div style="flex: 1">
                        <div style="width: 100%; height: 100%; overflow: auto" v-show="simulateStep === 0">
                            <a-form :model="simulateForm" ref="simulateInitConditionForm">
                                <div style="display: flex; flex-direction: row">
                                    <a-card
                                        style="flex: 1"
                                        :bodyStyle="{ padding: '8px' }"
                                        :headStyle="{ borderBottom: 'none', paddingLeft: '8px', paddingRight: '8px' }"
                                        :bordered="false"
                                    >
                                        <template #title>
                                            <span style="border-left: 4px solid #d7000f; padding-left: 8px"
                                                >基本信息</span
                                            >
                                        </template>
                                        <a-form-item
                                            label="方案名称"
                                            name="caseName"
                                            :rules="[{ required: true, message: '请输入方案名称' }]"
                                        >
                                            <a-input v-model:value="simulateForm.caseName" />
                                        </a-form-item>
                                    </a-card>
                                    <a-card
                                        style="flex: 1"
                                        :bodyStyle="{ padding: '8px' }"
                                        :headStyle="{ borderBottom: 'none', paddingLeft: '8px', paddingRight: '8px' }"
                                        :bordered="false"
                                    >
                                        <template #title>
                                            <span style="border-left: 4px solid #d7000f; padding-left: 8px"
                                                >模拟区域选择</span
                                            >
                                        </template>
                                        <a-input-search
                                            v-model:value="simulateAreaSearchValue"
                                            style="margin-bottom: 8px"
                                            placeholder="Search"
                                        />
                                        <a-form-item :label="''" :label-col="{ span: 0 }">
                                            <a-tree
                                                v-model:checkedKeys="simulateForm.areas"
                                                checkable
                                                :field-names="{ children: 'children', title: 'name', key: 'code' }"
                                                default-expand-all
                                                :tree-data="simulateTreeData"
                                            >
                                                <template #title="{ name }">
                                                    <span v-if="name.indexOf(simulateAreaSearchValue) > -1"
                                                        >{{ name.substr(0, name.indexOf(simulateAreaSearchValue))
                                                        }}<span style="color: #f50">{{ simulateAreaSearchValue }}</span
                                                        >{{
                                                            name.substr(
                                                                name.indexOf(simulateAreaSearchValue) +
                                                                    simulateAreaSearchValue.length
                                                            )
                                                        }}</span
                                                    >
                                                    <span v-else>{{ name }}</span>
                                                </template>
                                            </a-tree>
                                        </a-form-item>
                                    </a-card>
                                    <a-card
                                        style="flex: 1"
                                        :bodyStyle="{ padding: '8px' }"
                                        :headStyle="{ borderBottom: 'none', paddingLeft: '8px', paddingRight: '8px' }"
                                        :bordered="false"
                                    >
                                        <template #title>
                                            <span style="border-left: 4px solid #d7000f; padding-left: 8px"
                                                >约束设置</span
                                            >
                                        </template>
                                        <a-form-item
                                            label="最大降价额"
                                            name="maxPriceReductionAmount"
                                            :rules="[{ required: true, message: '请输入最大降价额' }]"
                                        >
                                            <a-input-number
                                                v-model:value="simulateForm.maxPriceReductionAmount"
                                                style="width: 100%"
                                            >
                                                <template #addonAfter> 元/吨 </template>
                                            </a-input-number>
                                        </a-form-item>
                                        <a-form-item
                                            label="最大提价额"
                                            name="maxPriceIncreaseAmount"
                                            :rules="[{ required: true, message: '请输入最大提价额' }]"
                                        >
                                            <a-input-number
                                                v-model:value="simulateForm.maxPriceIncreaseAmount"
                                                style="width: 100%"
                                            >
                                                <template #addonAfter> 元/吨 </template>
                                            </a-input-number>
                                        </a-form-item>
                                        <a-form-item
                                            label="市占率浮动下限"
                                            name="marketShareFluctuationLowerLimit"
                                            :rules="[{ required: true, message: '请输入市占率浮动下限' }]"
                                        >
                                            <a-space direction="horizontal">
                                                <a-form-item-rest>
                                                    <a-select
                                                        style="width: 4em"
                                                        v-model:value="
                                                            simulateForm.marketShareFluctuationLowerLimitSign
                                                        "
                                                    >
                                                        <a-select-option value="+">+</a-select-option>
                                                        <a-select-option value="-">-</a-select-option>
                                                    </a-select>
                                                </a-form-item-rest>
                                                <a-input-number
                                                    :min="0"
                                                    v-model:value="simulateForm.marketShareFluctuationLowerLimit"
                                                >
                                                    <template #addonAfter> % </template>
                                                </a-input-number>
                                            </a-space>
                                        </a-form-item>
                                        <a-form-item
                                            label="市占率浮动上限"
                                            name="marketShareFluctuationUpperLimit"
                                            :rules="[{ required: true, message: '请输入市占率浮动上限' }]"
                                        >
                                            <a-space direction="horizontal">
                                                <a-form-item-rest>
                                                    <a-select
                                                        style="width: 4em"
                                                        v-model:value="
                                                            simulateForm.marketShareFluctuationUpperLimitSign
                                                        "
                                                    >
                                                        <a-select-option value="+">+</a-select-option>
                                                        <a-select-option value="-">-</a-select-option>
                                                    </a-select>
                                                </a-form-item-rest>
                                                <a-input-number
                                                    :min="0"
                                                    v-model:value="simulateForm.marketShareFluctuationUpperLimit"
                                                >
                                                    <template #addonAfter> % </template>
                                                </a-input-number>
                                            </a-space>
                                        </a-form-item>
                                    </a-card>
                                </div>
                            </a-form>
                        </div>
                        <div style="width: 100%; height: 100%; overflow: auto" v-show="simulateStep === 1">
                            <div style="position: relative; height: 100%; width: 100%; padding-top: 24px">
                                <a-table
                                    :columns="simulatePredictionTableColumn"
                                    :data-source="simulatePredictionTableData"
                                    :loading="simulatePredictionTableLoading"
                                    size="small"
                                    :pagination="false"
                                    bordered
                                >
                                    <template #bodyCell="{ column, text, record }">
                                        <template v-if="column.dataIndex === 'cityDemandChange'">
                                            <a-input-number
                                                v-model:value="record.cityDemandChange"
                                                style="width: 100%"
                                            />
                                        </template>
                                    </template>
                                </a-table>
                            </div>
                        </div>
                        <div style="width: 100%; height: 100%; overflow: auto" v-show="simulateStep === 2">
                            <div style="position: relative; height: 100%; width: 100%; padding-top: 24px">
                                <a-spin :spinning="simulateCaseLoading">
                                    <a-descriptions :column="3">
                                        <a-descriptions-item label="预估模拟总效益空间"
                                            ><span style="color: #00f">{{
                                                isNaN(parseFloat(simulateCaseData.totalBenefitValue))
                                                    ? '--'
                                                    : simulateCaseData.totalBenefitValue
                                            }}</span>
                                            <span>万元</span></a-descriptions-item
                                        >
                                        <a-descriptions-item label="预估模拟前总销量"
                                            ><span style="color: #00f">{{
                                                isNaN(parseFloat(simulateCaseData.totalSale))
                                                    ? '--'
                                                    : simulateCaseData.totalSale
                                            }}</span>
                                            <span>万吨</span></a-descriptions-item
                                        >
                                        <a-descriptions-item label="预估最优销量"
                                            ><span style="color: #00f">{{
                                                isNaN(parseFloat(simulateCaseData.beforeTotalSale))
                                                    ? '--'
                                                    : simulateCaseData.beforeTotalSale
                                            }}</span>
                                            <span>万吨</span></a-descriptions-item
                                        >
                                    </a-descriptions>
                                    <div>
                                        <a-radio-group v-model:value="simulateSelectProduct">
                                            <a-radio-button
                                                v-for="item in simulateProductList"
                                                :key="item"
                                                :value="item"
                                                >{{ item }}</a-radio-button
                                            >
                                        </a-radio-group>
                                    </div>
                                    <div>
                                        <a-table
                                            :columns="simulateCaseTableColumn"
                                            :data-source="simulateCaseTableData"
                                            size="small"
                                            :scroll="{ x: 1265 }"
                                            :pagination="false"
                                            bordered
                                        >
                                            <template #bodyCell="{ column, text, record }">
                                                <template v-if="column.dataIndex === 'occPred'">
                                                    <span
                                                        v-if="record.occPred > record.beforeOccPred"
                                                        style="color: red"
                                                    >
                                                        {{ text }}
                                                        <arrow-up-outlined />
                                                    </span>
                                                    <span
                                                        v-else-if="record.occPred < record.beforeOccPred"
                                                        style="color: darkgreen"
                                                    >
                                                        {{ text }}
                                                        <arrow-down-outlined />
                                                    </span>
                                                    <span v-else>{{ text }}</span>
                                                </template>
                                                <template v-if="column.dataIndex === 'cityPrice'">
                                                    {{ text }}
                                                    <small
                                                        v-if="record.cityPrice > record.beforeCityPrice"
                                                        style="color: red"
                                                    >
                                                        + {{ record.cityPrice - record.beforeCityPrice }}
                                                    </small>
                                                    <small
                                                        v-else-if="record.cityPrice < record.beforeCityPrice"
                                                        style="color: darkgreen"
                                                    >
                                                        - {{ record.beforeCityPrice - record.cityPrice }}
                                                    </small>
                                                </template>
                                                <template v-if="column.dataIndex === 'cityTotalSales'">
                                                    <span
                                                        v-if="record.cityTotalSales > record.beforeCityTotalSales"
                                                        style="color: red"
                                                    >
                                                        {{ text }}
                                                        <arrow-up-outlined />
                                                    </span>
                                                    <span
                                                        v-else-if="record.cityTotalSales < record.beforeCityTotalSales"
                                                        style="color: darkgreen"
                                                    >
                                                        {{ text }}
                                                        <arrow-down-outlined />
                                                    </span>
                                                    <span v-else>{{ text }}</span>
                                                </template>

                                                <template v-if="column.dataIndex === 'cityBenefitValue'">
                                                    <span
                                                        v-if="record.cityBenefitValue > record.cityBeforeBenefitValue"
                                                        style="color: red"
                                                    >
                                                        + {{ record.cityBenefitValue - record.cityBeforeBenefitValue }}
                                                    </span>
                                                    <span
                                                        v-else-if="
                                                            record.cityBenefitValue < record.cityBeforeBenefitValue
                                                        "
                                                        style="color: darkgreen"
                                                    >
                                                        - {{ record.cityBeforeBenefitValue - record.cityBenefitValue }}
                                                    </span>
                                                    <span v-else>0</span>
                                                </template>

                                                <template v-if="column.dataIndex === 'beforeBenefitValue'">
                                                    <span
                                                        v-if="record.benefitValue > record.beforeBenefitValue"
                                                        style="color: red"
                                                    >
                                                        + {{ record.benefitValue - record.beforeBenefitValue }}
                                                    </span>
                                                    <span
                                                        v-else-if="record.benefitValue < record.beforeBenefitValue"
                                                        style="color: darkgreen"
                                                    >
                                                        - {{ record.beforeBenefitValue - record.benefitValue }}
                                                    </span>
                                                    <span v-else>0</span>
                                                </template>
                                            </template>
                                        </a-table>
                                    </div>
                                </a-spin>
                            </div>
                        </div>
                    </div>
                </div>
                <template #footer>
                    <div style="display: flex; flex-direction: row; justify-content: center">
                        <a-button @click="simulateModalVisible = false">取消</a-button>
                        <a-button type="primary" v-show="simulateStep > 0" @click="simulateStep--">上一步</a-button>
                        <a-button type="primary" v-show="simulateStep < 2" @click="handleSimulateNextStep"
                            >下一步</a-button
                        >

                        <a-button
                            :loading="simulateCaseLoading"
                            type="primary"
                            v-show="simulateStep === 2"
                            @click="simulate"
                        >
                            <template v-if="simulateCaseLoading">模拟中</template>
                            <template v-else>重新模拟</template>
                        </a-button>
                        <a-button
                            :loading="savingSimulate"
                            type="primary"
                            v-show="simulateStep === 2"
                            @click="saveSimulate"
                            >保存</a-button
                        >
                    </div>
                </template>
            </a-modal>
            <!-- end vid_xjg6gqqxpp 自定义模板_h1df8suis4 -->
        </a-spin>
    </div>
</template>
<script setup lang="tsx">
    import {
        h,
        ref,
        reactive,
        toRaw,
        markRaw,
        watch,
        computed,
        onBeforeMount,
        onMounted,
        onBeforeUnmount,
        onUnmounted,
        onActivated,
        onDeactivated
    } from 'vue'
    import { useRoute, useRouter } from 'vue-router'
    const router = useRouter()
    const route = useRoute()
    import { get, post, put, del, request, requestWithHeaders } from '@/utils/http/Axios'
    import {
        cloneDeep,
        localGet,
        merge,
        getDifferenceArray,
        traversalTreeStructure,
        checkCaseCondition,
        renderStringInTemplate,
        handleBreadcrumbJump,
        throttle,
        permission,
        getComponentParamsValue
    } from '@/utils/index'
    import { isNullOrEmpty, isEmptyArr, isNullOrUnDef, isContained, isArray, isEmpty, isObject } from '@/utils/is'
    import dayjs from 'dayjs'
    import { getPagePcChartsDataSourceConvert } from '@/utils/chart'
    import { message, notification, Modal } from 'ant-design-vue'
    import {
        propertyFormatByNumber,
        propertyFormatByPercentage,
        propertyFormatByDate,
        parseSubFromDataList
    } from '@/utils/format'
    import colorTheme from '@/design/custom-theme.json'
    /*** PUBLISH_EXEGESIS ***
 import UserTableRecords from '@/model/UserTableRecords';
 import { getAppBaseUrl } from '@/utils/index';
 import { sendToken } from "@/hooks/useIframeToken";
 import { useSystemStore } from "@/store/modules/system";
 const systemStore = useSystemStore();
 *** PUBLISH_EXEGESIS ***/

    // 获取传入的流程ID和组件参数
    const props = defineProps({
        'processInstanceId': {
            type: [String, Number, Boolean],
            default: undefined
        }
    })
    const immediateWatch = (source, callback) => {
        watch(source, callback, { deep: true, immediate: true })
    }

    /* -------------------------- 属性定义 -------------------------- */

    const setTimeOutList = []
    const pageLoading = reactive({
        loading: false,
        tip: undefined
    })
    const authInfo = localGet('app-user-store')

    // 处理校验
    const setSubFormName = (parentInfo, name) => {
        return [parentInfo.parents, parentInfo.cycleIndex, name]
    }

    /* ========================== 属性定义 ========================== */

    /* -------------------------- 元素数据引用 -------------------------- */

    /* ========================== 元素数据引用 ========================== */

    /* -------------------------- 页面数据 -------------------------- */

    /* ========================== 页面数据 ========================== */

    /* -------------------------- 响应 -------------------------- */

    /* ========================== 响应 ========================== */

    /* -------------------------- 函数 -------------------------- */

    /* ========================== 函数 ========================== */

    /* -------------------------- 页面参数 -------------------------- */

    const pageParameter_state = reactive({
        'processInstanceId': props.processInstanceId ?? route.query.processInstanceId
    })

    /* ========================== 页面参数 ========================== */

    /* -------------------------- 组件事件处理方法 -------------------------- */

    // ---------------------------- 组件数据同步 ----------------------------

    // ============================ 组件数据同步 ============================

    /* ========================== 组件事件处理方法 ========================== */

    /* -------------------------- 生命周期 -------------------------- */
    // 用于参数变更后重新执行自定义指令
    const queryUpdateFlag = ref(0)
    onMounted(() => {})

    onUnmounted(() => {
        // 销毁定时器
        setTimeOutList.forEach(({ repeat, timer }) => {
            repeat ? clearInterval(timer) : clearTimeout(timer)
        })
    })

    /* ========================== 生命周期 ========================== */

    /* -------------------------- 数据关联处理 -------------------------- */

    /* -------------------------- 表单数据同步 -------------------------- */
    /* ========================== 表单数据同步 ========================== */

    /* ========================== 数据关联处理 ========================== */

    /* -------------------------- 不同组件自定义的处理逻辑 -------------------------- */

    /* ========================== 不同组件自定义的处理逻辑 ========================== */

    // ================================定制化逻辑========================================
    const cementType = ref([])
    const loadCementType = () => {
        return post('/dynamic-price/api/v1/base_info/search', {
            'filter': {
                'baseTypeId': 2
            },
            'pageSize': 9999,
            'pageNo': 1
        }).then(resp => {
            cementType.value = resp.data.content.map(item => item.name)
            config.cementType = cementType.value?.[0]
        })
    }

    const packageType = ref([])
    const loadPackageType = () => {
        return post('/dynamic-price/api/v1/base_info/search', {
            'filter': {
                'baseTypeId': 5
            },
            'pageSize': 9999,
            'pageNo': 1
        }).then(resp => {
            packageType.value = resp.data.content.map(item => item.name)
            config.packageType = [...packageType.value]
        })
    }
    // 地区选择器
    const area = ref('100000')
    const treeData = ref([])
    get('http://10.40.0.33:9001/file-storage/463304091817123840-source.json').then(res => {
        try {
            treeData.value = [
                {
                    adcode: '100000',
                    name: '全部区域',
                    districts: res
                }
            ]
        } catch (error) {
            console.log('error :', error)
        }
    })
    const handleAreaSelected = () => {
        // 平移地图
        mapData.map?.setCity(area.value[area.value.length - 1])
        // TODO: 其它动作
    }

    const layersConfig = reactive({
        enableEnterpriceLogo: false,
        enableEnterpriceName: false,
        enableEnterpriceCapacity: false
    })

    // 加载地图
    import AMapLoader from '@amap/amap-jsapi-loader'

    const markerPng = 'http://10.40.0.33:9001/file-storage/463538766877728768-source.png'
    let logoMap = {
        '北方水泥': 'http://10.40.0.33:9001/file-storage/463538766877728768-source.png',
        '冀东集团': 'http://10.40.0.33:9001/file-storage/463538766877728768-source.png',
        '亚泰集团': 'http://10.40.0.33:9001/file-storage/463538766877728768-source.png',
        '蒙西集团': 'http://10.40.0.33:9001/file-storage/463538766877728768-source.png',
        '天瑞集团': 'http://10.40.0.33:9001/file-storage/463538766877728768-source.png',
        '其他': 'http://10.40.0.33:9001/file-storage/463538766877728768-source.png'
    }
    window._AMapSecurityConfig = {
        securityJsCode: '37a7e520e06bc202ff267a6a0e492d13'
    }
    let provinceMapData = null
    let cityMapData = null
    let AMap = null
    let areaCodeAndCenterMap = {
        '150402': '红山区',
        '150403': '元宝山区',
        '150404': '松山区',
        '150421': '阿鲁科尔沁旗',
        '150422': '巴林左旗',
        '150423': '巴林右旗',
        '150424': '林西县',
        '150425': '克什克腾旗',
        '150426': '翁牛特旗',
        '150428': '喀喇沁旗',
        '150429': '宁城县',
        '150430': '敖汉旗',
        '150502': '科尔沁区',
        '150521': '科尔沁左翼中旗',
        '150522': '科尔沁左翼后旗',
        '150523': '开鲁县',
        '150524': '库伦旗',
        '150525': '奈曼旗',
        '150526': '扎鲁特旗',
        '150581': '霍林郭勒市',
        '150702': '海拉尔区',
        '150703': '扎赉诺尔区',
        '150721': '阿荣旗',
        '150722': '莫力达瓦达斡尔族自治旗',
        '150723': '鄂伦春自治旗',
        '150724': '鄂温克族自治旗',
        '150725': '陈巴尔虎旗',
        '150726': '新巴尔虎左旗',
        '150727': '新巴尔虎右旗',
        '150781': '满洲里市',
        '150782': '牙克石市',
        '150783': '扎兰屯市',
        '150784': '额尔古纳市',
        '150785': '根河市',
        '152201': '乌兰浩特市',
        '152202': '阿尔山市',
        '152221': '科尔沁右翼前旗',
        '152222': '科尔沁右翼中旗',
        '152223': '扎赉特旗',
        '152224': '突泉县',
        '152501': '二连浩特市',
        '152502': '锡林浩特市',
        '152522': '阿巴嘎旗',
        '152523': '苏尼特左旗',
        '152524': '苏尼特右旗',
        '152525': '东乌珠穆沁旗',
        '152526': '西乌珠穆沁旗',
        '152527': '太仆寺旗',
        '152528': '镶黄旗',
        '152529': '正镶白旗',
        '152530': '正蓝旗',
        '152531': '多伦县',
        '210102': '和平区',
        '210103': '沈河区',
        '210104': '大东区',
        '210105': '皇姑区',
        '210106': '铁西区',
        '210111': '苏家屯区',
        '210112': '浑南区',
        '210113': '沈北新区',
        '210114': '于洪区',
        '210115': '辽中区',
        '210123': '康平县',
        '210124': '法库县',
        '210181': '新民市',
        '210202': '中山区',
        '210203': '西岗区',
        '210204': '沙河口区',
        '210211': '甘井子区',
        '210212': '旅顺口区',
        '210213': '金州区',
        '210214': '普兰店区',
        '210224': '长海县',
        '210281': '瓦房店市',
        '210283': '庄河市',
        '210302': '铁东区',
        '210303': '铁西区',
        '210304': '立山区',
        '210311': '千山区',
        '210321': '台安县',
        '210323': '岫岩满族自治县',
        '210381': '海城市',
        '210402': '新抚区',
        '210403': '东洲区',
        '210404': '望花区',
        '210411': '顺城区',
        '210421': '抚顺县',
        '210422': '新宾满族自治县',
        '210423': '清原满族自治县',
        '210502': '平山区',
        '210503': '溪湖区',
        '210504': '明山区',
        '210505': '南芬区',
        '210521': '本溪满族自治县',
        '210522': '桓仁满族自治县',
        '210602': '元宝区',
        '210603': '振兴区',
        '210604': '振安区',
        '210624': '宽甸满族自治县',
        '210681': '东港市',
        '210682': '凤城市',
        '210702': '古塔区',
        '210703': '凌河区',
        '210711': '太和区',
        '210726': '黑山县',
        '210727': '义县',
        '210781': '凌海市',
        '210782': '北镇市',
        '210802': '站前区',
        '210803': '西市区',
        '210804': '鲅鱼圈区',
        '210811': '老边区',
        '210881': '盖州市',
        '210882': '大石桥市',
        '210902': '海州区',
        '210903': '新邱区',
        '210904': '太平区',
        '210905': '清河门区',
        '210911': '细河区',
        '210921': '阜新蒙古族自治县',
        '210922': '彰武县',
        '211002': '白塔区',
        '211003': '文圣区',
        '211004': '宏伟区',
        '211005': '弓长岭区',
        '211011': '太子河区',
        '211021': '辽阳县',
        '211081': '灯塔市',
        '211102': '双台子区',
        '211103': '兴隆台区',
        '211104': '大洼区',
        '211122': '盘山县',
        '211202': '银州区',
        '211204': '清河区',
        '211221': '铁岭县',
        '211223': '西丰县',
        '211224': '昌图县',
        '211281': '调兵山市',
        '211282': '开原市',
        '211302': '双塔区',
        '211303': '龙城区',
        '211321': '朝阳县',
        '211322': '建平县',
        '211324': '喀喇沁左翼蒙古族自治县',
        '211381': '北票市',
        '211382': '凌源市',
        '220102': '南关区',
        '220103': '宽城区',
        '220104': '朝阳区',
        '220105': '二道区',
        '220106': '绿园区',
        '220112': '双阳区',
        '220113': '九台区',
        '220122': '农安县',
        '220182': '榆树市',
        '220183': '德惠市',
        '220202': '昌邑区',
        '220203': '龙潭区',
        '220204': '船营区',
        '220211': '丰满区',
        '220221': '永吉县',
        '220281': '蛟河市',
        '220282': '桦甸市',
        '220283': '舒兰市',
        '220284': '磐石市',
        '211402': '连山区',
        '211403': '龙港区',
        '211404': '南票区',
        '211421': '绥中县',
        '211422': '建昌县',
        '211481': '兴城市',
        '220302': '铁西区',
        '220303': '铁东区',
        '220322': '梨树县',
        '220323': '伊通满族自治县',
        '220381': '公主岭市',
        '220382': '双辽市',
        '220402': '龙山区',
        '220403': '西安区',
        '220421': '东丰县',
        '220422': '东辽县',
        '220502': '东昌区',
        '220503': '二道江区',
        '220521': '通化县',
        '220523': '辉南县',
        '220524': '柳河县',
        '220581': '梅河口市',
        '220582': '集安市',
        '220602': '浑江区',
        '220605': '江源区',
        '220621': '抚松县',
        '220622': '靖宇县',
        '220623': '长白朝鲜族自治县',
        '220681': '临江市',
        '220702': '宁江区',
        '220721': '前郭尔罗斯蒙古族自治县',
        '220722': '长岭县',
        '220723': '乾安县',
        '220781': '扶余市',
        '220802': '洮北区',
        '220821': '镇赉县',
        '220822': '通榆县',
        '220881': '洮南市',
        '220882': '大安市',
        '222401': '延吉市',
        '222402': '图们市',
        '222403': '敦化市',
        '222404': '珲春市',
        '222405': '龙井市',
        '222406': '和龙市',
        '222424': '汪清县',
        '222426': '安图县',
        '230102': '道里区',
        '230103': '南岗区',
        '230104': '道外区',
        '230108': '平房区',
        '230109': '松北区',
        '230110': '香坊区',
        '230111': '呼兰区',
        '230112': '阿城区',
        '230113': '双城区',
        '230123': '依兰县',
        '230124': '方正县',
        '230125': '宾县',
        '230126': '巴彦县',
        '230127': '木兰县',
        '230128': '通河县',
        '230129': '延寿县',
        '230183': '尚志市',
        '230184': '五常市',
        '230202': '龙沙区',
        '230203': '建华区',
        '230204': '铁锋区',
        '230205': '昂昂溪区',
        '230206': '富拉尔基区',
        '230207': '碾子山区',
        '230208': '梅里斯达斡尔族区',
        '230221': '龙江县',
        '230223': '依安县',
        '230224': '泰来县',
        '230225': '甘南县',
        '230227': '富裕县',
        '230229': '克山县',
        '230230': '克东县',
        '230231': '拜泉县',
        '230281': '讷河市',
        '230402': '向阳区',
        '230403': '工农区',
        '230404': '南山区',
        '230405': '兴安区',
        '230406': '东山区',
        '230407': '兴山区',
        '230421': '萝北县',
        '230422': '绥滨县',
        '230302': '鸡冠区',
        '230303': '恒山区',
        '230304': '滴道区',
        '230305': '梨树区',
        '230306': '城子河区',
        '230307': '麻山区',
        '230321': '鸡东县',
        '230381': '虎林市',
        '230382': '密山市',
        '230502': '尖山区',
        '230503': '岭东区',
        '230505': '四方台区',
        '230506': '宝山区',
        '230521': '集贤县',
        '230522': '友谊县',
        '230523': '宝清县',
        '230524': '饶河县',
        '230602': '萨尔图区',
        '230603': '龙凤区',
        '230604': '让胡路区',
        '230605': '红岗区',
        '230606': '大同区',
        '230621': '肇州县',
        '230622': '肇源县',
        '230623': '林甸县',
        '230624': '杜尔伯特蒙古族自治县',
        '230702': '伊春区',
        '230703': '南岔区',
        '230704': '友好区',
        '230705': '西林区',
        '230706': '翠峦区',
        '230707': '新青区',
        '230708': '美溪区',
        '230709': '金山屯区',
        '230710': '五营区',
        '230711': '乌马河区',
        '230712': '汤旺河区',
        '230713': '带岭区',
        '230714': '乌伊岭区',
        '230715': '红星区',
        '230716': '上甘岭区',
        '230722': '嘉荫县',
        '230781': '铁力市',
        '230803': '向阳区',
        '230804': '前进区',
        '230805': '东风区',
        '230811': '郊区',
        '230822': '桦南县',
        '230826': '桦川县',
        '230828': '汤原县',
        '230881': '同江市',
        '230882': '富锦市',
        '230883': '抚远市',
        '230902': '新兴区',
        '230903': '桃山区',
        '230904': '茄子河区',
        '230921': '勃利县',
        '231002': '东安区',
        '231003': '阳明区',
        '231004': '爱民区',
        '231005': '西安区',
        '231025': '林口县',
        '231081': '绥芬河市',
        '231083': '海林市',
        '231084': '宁安市',
        '231085': '穆棱市',
        '231086': '东宁市',
        '231102': '爱辉区',
        '231121': '嫩江市',
        '231123': '逊克县',
        '231124': '孙吴县',
        '231181': '北安市',
        '231182': '五大连池市',
        '232701': '漠河市',
        '232718': '加格达奇区',
        '232721': '呼玛县',
        '232722': '塔河县',
        '231202': '北林区',
        '231221': '望奎县',
        '231222': '兰西县',
        '231223': '青冈县',
        '231224': '庆安县',
        '231225': '明水县',
        '231226': '绥棱县',
        '231281': '安达市',
        '231282': '肇东市',
        '231283': '海伦市'
    }
    const mapData = {
        map: null,
        loca: null,
        locationData: null,
        cityData: null,
        // 地图上各种图层
        layers: {}
    }
    // 地级市编码
    const cityInfoMap = {}

    // 加载地图所需的数据，在地图初始化前进行处理
    const initData = () => {
        let locationDataPromise = get('http://10.40.0.33:9001/file-storage/463538652597624832-source.json').then(
            resp => {
                mapData.locationData = resp
            }
        )
        let provinceMapDataPromise = get('http://10.40.0.33:9001/file-storage/465611071699197952-source.json').then(
            resp => {
                provinceMapData = resp
            }
        )
        let cityMapDataPromise = get('http://10.40.0.33:9001/file-storage/465647932513624064-source.json').then(
            resp => {
                cityMapData = resp
                cityMapData.features.forEach(item => {
                    cityInfoMap[item.properties.adcode] = item.properties
                })
            }
        )
        let cityPromise = get('http://10.40.0.33:9001/file-storage/463538588126978048-source.json').then(res => {
            mapData.city = res
        })
        return Promise.all([locationDataPromise, provinceMapDataPromise, cityMapDataPromise, cityPromise])
    }
    // 初始化地图
    const initMap = () => {
        return AMapLoader.load({
            key: '09b7ca63fd0a1ac64f96409c63347962', // 申请好的Web端开发者Key，首次调用 load 时必填
            version: '2.0', // 指定要加载的 JSAPI 的版本，缺省时默认为 1.4.15
            plugins: ['Map3D', 'AMap.DistrictSearch', 'AMap.Geocoder'], //需要使用的的插件列表，如比例尺'AMap.Scale'，支持添加多个如：['...','...']
            Loca: {
                // 是否加载 Loca， 缺省不加载
                version: '2.0.0' // Loca 版本，缺省 1.3.2
            }
        }).then(AMapInstancec => {
            AMap = AMapInstancec
            mapData.map = new AMap.Map('MapContainer', {
                mapStyle: 'amap://styles/whitesmoke',
                viewMode: '3D',
                showLabel: false,
                pitch: 60,
                zoom: 6.6,
                center: [126.173379, 44.929945]
            })
            mapData.loca = window.loca = new Loca.Container({
                map: mapData.map
            })
            // 隐藏天空图层
            mapData.map
                .getLayers()
                .filter(item => {
                    return item.CLASS_NAME === 'AMap.SkyLayer'
                })
                .forEach(layer => {
                    layer.hide()
                })
            mapData.map.setFitView()
            mapData.map.setZoom(6.6)
            mapData.map.panTo([126.173379, 44.929945])

            currentZoom.value = mapData.map.getZoom()
            mapData.map.on('zoomend', () => {
                currentZoom.value = mapData.map.getZoom()
                renderDistrictLayer()
            })
            return mapData.map
        })
    }
    // 绘制行政区划，并随地图层级变化而切换
    const renderDistrictLayer = () => {
        const colorMap = ['#ff83a5', '#ffd3d3', '#fca3b6', '#ffbebe', '#fd92ad', '#ff5d89', '#fca3b6']

        if (mapData.layers.districtLayer == null) {
            mapData.layers.districtLayer = {}
            mapData.layers.districtLayer.povince = new Loca.PolygonLayer({
                loca: mapData.loca,
                zIndex: 11,
                opacity: 0.99,
                shininess: 10,
                hasSide: true
            })
            mapData.layers.districtLayer.povince.setSource(
                new Loca.GeoJSONSource({
                    data: provinceMapData
                })
            )

            mapData.layers.districtLayer.povince.setStyle({
                topColor: function (index, feature) {
                    return colorMap[index % 7]
                },
                sideTopColor: function (index, feature) {
                    return '#ff5d89'
                },
                sideBottomColor: function (index, feature) {
                    return '#fa98ae'
                },
                height: function (index, feature) {
                    return 10000
                },
                altitude: 0,
                label: function (index, feature) {
                    // 后续定制区域名称
                    return {
                        visible: true,
                        name: 'wallLayerLabel',
                        text: {
                            content: '' + feature.properties.name,
                            style: {
                                fillColor: '#FFFFFF'
                            }
                        }
                    }
                }
            })

            mapData.layers.districtLayer.city = new Loca.PolygonLayer({
                loca: mapData.loca,
                zIndex: 11,
                opacity: 0.99,
                shininess: 10,
                hasSide: true
            })
            mapData.layers.districtLayer.city.setSource(
                new Loca.GeoJSONSource({
                    data: cityMapData
                })
            )

            mapData.layers.districtLayer.city.setStyle({
                topColor: function (index, feature) {
                    return colorMap[index % 7]
                },
                sideTopColor: function (index, feature) {
                    return '#ff5d89'
                },
                sideBottomColor: function (index, feature) {
                    return '#fa98ae'
                },
                height: function (index, feature) {
                    return 10000
                },
                altitude: 0,
                label: function (index, feature) {
                    // 后续定制区域名称
                    return {
                        visible: true,
                        name: 'wallLayerLabel',
                        text: {
                            content: '' + feature.properties.name,
                            style: {
                                fillColor: '#FFFFFF'
                            }
                        }
                    }
                }
            })

            mapData.layers.districtLayer.country = new Loca.PolygonLayer({
                loca: mapData.loca,
                zIndex: 11,
                opacity: 0.99,
                shininess: 10,
                hasSide: true
            })

            let data = []
            mapData.city.forEach(item => {
                data = data.concat(
                    item.features.map(item => {
                        return item
                    })
                )
            })
            mapData.layers.districtLayer.country.setSource(
                new Loca.GeoJSONSource({
                    data: {
                        type: 'FeatureCollection',
                        features: data
                    }
                })
            )

            mapData.layers.districtLayer.country.setStyle({
                topColor: function (index, feature) {
                    return colorMap[index % 7]
                },
                sideTopColor: function (index, feature) {
                    return '#ff5d89'
                },
                sideBottomColor: function (index, feature) {
                    return '#fa98ae'
                },
                height: function (index, feature) {
                    return 10000
                },
                altitude: 0,
                label: function (index, feature) {
                    // 后续定制区域名称
                    return {
                        visible: true,
                        name: 'wallLayerLabel',
                        text: {
                            content: '' + feature.properties.name,
                            style: {
                                fillColor: '#FFFFFF'
                            }
                        }
                    }
                }
            })

            mapData.map.on('click', e => {
                let properties = null
                if (showProvince.value) {
                    const feat = mapData.layers.districtLayer.povince.queryFeature(e.pixel.toArray())
                    properties = feat?.properties
                } else if (showCity.value) {
                    const feat = mapData.layers.districtLayer.city.queryFeature(e.pixel.toArray())
                    properties = feat?.properties
                } else {
                    const feat = mapData.layers.districtLayer.country.queryFeature(e.pixel.toArray())
                    properties = feat?.properties
                }
                if (properties?.adcode && properties?.name) {
                    showAreaInfo(properties.adcode, properties.name, properties.level)
                }
            })
        }
        // 构建 geo data
        if (showProvince.value) {
            mapData.layers.districtLayer.povince.show()
            mapData.layers.districtLayer.city.hide()
            mapData.layers.districtLayer.country.hide()
        } else if (showCity.value) {
            mapData.layers.districtLayer.povince.hide()
            mapData.layers.districtLayer.city.show()
            mapData.layers.districtLayer.country.hide()
        } else {
            mapData.layers.districtLayer.povince.hide()
            mapData.layers.districtLayer.city.hide()
            mapData.layers.districtLayer.country.show()
        }
    }

    const enterpriceListData = computed(() => {
        let result = []
        if (pageData.rawData?.sandBoxAreaDtoList) {
            if (pageData.rawData?.sandBoxAreaDtoList.length > 0) {
                pageData.rawData?.sandBoxAreaDtoList.forEach(item => {
                    if (item.sandBoxEnterpriceDtoList) {
                        result.push(...item.sandBoxEnterpriceDtoList)
                    }
                })
            }
        }
        return result
    })
    // 绘制企业logo
    const renderEnterpriceLogoLayer = () => {
        if (mapData.layers.enterpriceLogoLayer === null || mapData.layers.enterpriceLogoLayer === undefined) {
            mapData.layers.enterpriceLogoLayer = new AMap.OverlayGroup([])
            mapData.map.add(mapData.layers)
        }
        let layer = mapData.layers.enterpriceLogoLayer
        // 清理图层
        layer.eachOverlay(item => {
            mapData.map?.remove(item)
        })
        layer.clearOverlays()

        // 获取全部marker
        let markers = []
        enterpriceListData.value.forEach(enterprice => {
            let content = '<div class="custom-content-marker">'
            // 企业按不同Logo区分北方水泥、、亚泰、蒙西、天瑞、其他（除前面提到的外）
            let logo = logoMap[enterprice.groupName] ?? markerPng
            content += `<img src="${logo}" class="icon" style="width: 24px;height: 24px;" alt=""/>`
            content += '</div>'

            let marker = new AMap.Marker({
                map: mapData.map,
                position: [enterprice.longitude, enterprice.latitude, 10000],
                title: enterprice.enterpriceName,
                content,
                anchor: 'middle-left',
                extData: {
                    position: [enterprice.longitude, enterprice.latitude, 10000],
                    title: enterprice.enterpriceName,
                    type: 'mill'
                }
            })
            marker.on('click', function (e) {
                console.log('你点击了Marker', e)
            })
            markers.push(marker)
        })
        if (markers.length > 0) {
            layer.addOverlays([...markers])
        }

        if (layersConfig?.enableEnterpriceLogo) {
            mapData.layers?.enterpriceLogoLayer?.eachOverlay(item => {
                item.show()
            })
        } else {
            mapData.layers?.enterpriceLogoLayer?.eachOverlay(item => {
                item.hide()
            })
        }
    }
    watch(
        () => '' + layersConfig.enableEnterpriceLogo,
        () => {
            if (layersConfig?.enableEnterpriceLogo) {
                mapData.layers?.enterpriceLogoLayer?.eachOverlay(item => {
                    item.show()
                })
            } else {
                mapData.layers?.enterpriceLogoLayer?.eachOverlay(item => {
                    item.hide()
                })
            }
        },
        {
            deep: true
        }
    )

    // 绘制企业名称
    const renderEnterpriceNameLayer = () => {
        if (mapData.layers.enterpriceNameLayer === null || mapData.layers.enterpriceNameLayer === undefined) {
            mapData.layers.enterpriceNameLayer = new AMap.OverlayGroup([])
            mapData.map.add(mapData.layers)
        }
        let layer = mapData.layers.enterpriceNameLayer
        // 清理图层
        layer.eachOverlay(item => {
            mapData.map?.remove(item)
        })
        layer.clearOverlays()

        // 获取全部marker
        let markers = []
        enterpriceListData.value.forEach(enterprice => {
            let content = '<div class="custom-content-marker" style="padding-left: 24px;">'

            let style = 'color:#000;font-size: 12px;'
            if (enterprice.classify === '内部企业') {
                style = 'color:#F00;font-size: 16px;'
            }

            let stopStatus = ''
            if (enterprice.enterpriceStatus === '关闭') {
                stopStatus = '*'
            }
            content += `<span style="${style}">${enterprice.enterpriceName}<sup>${stopStatus}</sup></span>`

            content += '</div>'

            let marker = new AMap.Marker({
                map: mapData.map,
                position: [enterprice.longitude, enterprice.latitude, 10000],
                title: enterprice.enterpriceName,
                content,
                offset: [2, -12],
                // anchor: "middle-left",
                extData: {
                    position: [enterprice.longitude, enterprice.latitude, 10000],
                    title: enterprice.enterpriceName,
                    type: 'mill'
                }
            })
            marker.on('click', function (e) {
                console.log('你点击了Marker', e)
            })
            markers.push(marker)
        })
        if (markers.length > 0) {
            layer.addOverlays([...markers])
        }

        if (layersConfig?.enableEnterpriceName) {
            mapData.layers?.enterpriceNameLayer?.eachOverlay(item => {
                item.show()
            })
        } else {
            mapData.layers?.enterpriceNameLayer?.eachOverlay(item => {
                item.hide()
            })
        }
    }
    watch(
        () => '' + layersConfig.enableEnterpriceName,
        () => {
            if (layersConfig?.enableEnterpriceName) {
                mapData.layers?.enterpriceNameLayer?.eachOverlay(item => {
                    item.show()
                })
            } else {
                mapData.layers?.enterpriceNameLayer?.eachOverlay(item => {
                    item.hide()
                })
            }
        },
        {
            deep: true
        }
    )

    // 绘制企业产能
    const renderEnterpriceCapacityLayer = () => {
        if (mapData.layers.enterpriceCapacityLayer === null || mapData.layers.enterpriceCapacityLayer === undefined) {
            mapData.layers.enterpriceCapacityLayer = new AMap.OverlayGroup([])
            mapData.map.add(mapData.layers)
        }
        let layer = mapData.layers.enterpriceCapacityLayer
        // 清理图层
        layer.eachOverlay(item => {
            mapData.map?.remove(item)
        })
        layer.clearOverlays()

        // 获取全部marker
        let markers = []
        enterpriceListData.value.forEach(enterprice => {
            let content = '<div class="custom-content-marker">'

            let capacityList = ''
            if (enterprice.capacityList && enterprice.capacityList.length > 0) {
                capacityList = '<span>' + enterprice.capacityList.join(' ') + '</span>'
            }
            content += capacityList

            content += '</div>'

            let marker = new AMap.Marker({
                map: mapData.map,
                position: [enterprice.longitude, enterprice.latitude, 10000],
                title: enterprice.enterpriceCapacity,
                content,
                offset: [24, 10],
                extData: {
                    position: [enterprice.longitude, enterprice.latitude, 10000],
                    title: enterprice.enterpriceCapacity,
                    type: 'mill'
                }
            })
            marker.on('click', function (e) {
                console.log('你点击了Marker', e)
            })
            markers.push(marker)
        })
        if (markers.length > 0) {
            layer.addOverlays([...markers])
        }

        if (layersConfig?.enableEnterpriceCapacity) {
            mapData.layers?.enterpriceCapacityLayer?.eachOverlay(item => {
                item.show()
            })
        } else {
            mapData.layers?.enterpriceCapacityLayer?.eachOverlay(item => {
                item.hide()
            })
        }
    }
    watch(
        () => '' + layersConfig.enableEnterpriceCapacity,
        () => {
            if (layersConfig?.enableEnterpriceCapacity) {
                mapData.layers?.enterpriceCapacityLayer?.eachOverlay(item => {
                    item.show()
                })
            } else {
                mapData.layers?.enterpriceCapacityLayer?.eachOverlay(item => {
                    item.hide()
                })
            }
        },
        {
            deep: true
        }
    )

    // 城市需求与库存数据
    const renderCityRequireAndInventoryData = computed(() => {
        // 提取地级市的数据
        let cityCode = Object.keys(cityInfoMap)
        return (
            pageData.rawData?.sandBoxAreaDtoList
                .filter(item => {
                    return cityCode.indexOf(item.code) > -1
                })
                .filter(item => {
                    return item.requireAndInventoryList && item.requireAndInventoryList.length >= 2
                })
                .map(item => {
                    let info = cityInfoMap[item.code]
                    return {
                        code: item.code,
                        areaName: item.areaName,
                        require: item.requireAndInventoryList[0],
                        inventory: item.requireAndInventoryList[0],
                        longitude: info.center[0],
                        latitude: info.center[1]
                    }
                }) ?? []
        )
    })

    // 绘制城市需求与库存
    const renderCityRequireAndInventoryLayer = () => {
        if (
            mapData.layers.cityRequireAndInventoryLayer === null ||
            mapData.layers.cityRequireAndInventoryLayer === undefined
        ) {
            mapData.layers.cityRequireAndInventoryLayer = new AMap.OverlayGroup([])
            mapData.map.add(mapData.layers)
        }

        let layer = mapData.layers.cityRequireAndInventoryLayer
        // 清理图层
        layer.eachOverlay(item => {
            mapData.map?.remove(item)
        })
        layer.clearOverlays()

        // 获取全部marker
        let markers = []
        renderCityRequireAndInventoryData.value.forEach(enterprice => {
            let content =
                '<div class="custom-content-marker" style="background:#FFF;padding: 4px;border-radius: 4px;display:flex;flex-direction:row;">'

            content += `<span style="padding: 0 4px 0 4px;border-right: 1px solid red;">区域需求 ${enterprice.require}万吨</span><span style="padding: 0 4px 4px">熟料库存 ${enterprice.inventory}万吨</span>`

            content += '</div>'

            let marker = new AMap.Marker({
                map: mapData.map,
                position: [enterprice.longitude, enterprice.latitude, 10000],
                title: enterprice.areaName,
                content,
                offset: [24, 10],
                extData: {
                    position: [enterprice.longitude, enterprice.latitude, 10000],
                    title: enterprice.areaName,
                    type: 'mill'
                }
            })
            marker.on('click', function (e) {
                console.log('你点击了Marker', e)
            })
            markers.push(marker)
        })
        if (markers.length > 0) {
            layer.addOverlays([...markers])
        }

        if (layersConfig?.enableCityRequireAndInventory) {
            mapData.layers?.cityRequireAndInventoryLayer?.eachOverlay(item => {
                item.show()
            })
        } else {
            mapData.layers?.cityRequireAndInventoryLayer?.eachOverlay(item => {
                item.hide()
            })
        }
    }
    watch(
        () => '' + layersConfig.enableCityRequireAndInventory,
        () => {
            if (layersConfig?.enableCityRequireAndInventory) {
                mapData.layers?.cityRequireAndInventoryLayer?.eachOverlay(item => {
                    item.show()
                })
            } else {
                mapData.layers?.cityRequireAndInventoryLayer?.eachOverlay(item => {
                    item.hide()
                })
            }
        },
        {
            deep: true
        }
    )

    const currentZoom = ref(0)
    const showProvince = computed(() => {
        return currentZoom.value < 7
    })
    const showCity = computed(() => {
        let zoom = currentZoom.value ?? 0
        return zoom >= 7 && zoom < 10
    })
    const showCountry = computed(() => {
        return currentZoom.value >= 10
    })
    const enableMap3D = ref(true)
    const changeMap3D = value => {
        console.log(value)
        if (value) {
            mapData.map?.setPitch(60)
        } else {
            mapData.map?.setPitch(0)
        }
    }

    onMounted(() => {
        initData()
            .then(() => {
                return initMap()
            })
            .then(data => {
                return renderDistrictLayer()
            })
            .then(() => {
                return loadMapData()
            })
            .then(() => {
                return renderEnterpriceLogoLayer()
            })
            .then(() => {
                return renderEnterpriceNameLayer()
            })
            .then(() => {
                renderCityRequireAndInventoryLayer()
                return renderEnterpriceCapacityLayer()
            })
    })

    const config = reactive({
        cementType: null,
        packageType: null
    })
    const pageData = reactive({
        rawData: null,
        inventory: null
    })

    watch(
        () => config,
        () => {
            loadMapData()
        },
        {
            deep: true
        }
    )

    // 加载地图数据
    const loadMapData = () => {
        let loadBasicDataPromise = Promise.resolve()
        if (cementType.value.length <= 0) {
            loadBasicDataPromise = Promise.all([loadCementType(), loadPackageType()])
        }
        return loadBasicDataPromise.then(() => {
            const loadPageDataPromise = post('/dynamic-price/api/v2/timed_pricing_optimization/search', {
                cementVarity: config.cementType,
                packageList: config.packageType
            }).then(resp => {
                pageData.rawData = resp.data
            })
            const loadInventoryPromise = post('/dynamic-price/api/v1/timed_pricing_optimization/inventory_search', {
                cementVarity: config.cementType,
                packageList: config.packageType
            }).then(resp => {
                pageData.inventory = resp.data
            })
            return Promise.all([loadPageDataPromise, loadInventoryPromise])
            // pageData.inventory = 0
            // return get('http://10.40.0.33:9001/file-storage/465653301958844416-source.json').then(res => {
            //     pageData.rawData = res
            // })
        })
    }

    ///############### 右侧弹窗
    ///  弹窗控制
    const drawerVisible = ref(false)
    const showAreaInfoLevel = ref('')
    const showAreaInfoName = ref('')
    const showAreaInfoCode = ref('')
    const onClose = () => {
        drawerVisible.value = false
        // cleanPriceDiffLayer()
    }
    const showAreaInfo = (code, name, level) => {
        // 显示区域信息
        drawerVisible.value = true
        showAreaInfoLevel.value = level
        showAreaInfoName.value = name
        showAreaInfoCode.value = code
        // priceDiffArea.value = code

        // 清空信息
        areaInfoType.value = null
        areaBasicInfo = null
        areaInfoTableData.value = []

        loadAreaInfo()

        //
        areaInfoPriceDiffType.value = cementType.value?.[0]
        areaInfoPriceDiffRawData.value = {}
        loadAreaInfoPriceDiff()
    }

    // 弹窗企业信息
    const areaInfoTableColumns = [
        {
            title: '企业名称',
            dataIndex: 'enterpriseName',
            align: 'center',
            key: 'enterpriseName'
        },
        {
            title: '到位价（元/吨）',
            align: 'center',
            children: [
                {
                    title: '当前价',
                    dataIndex: 'currentPrice',
                    align: 'center',
                    key: 'currentPrice'
                },
                {
                    title: '建议价',
                    dataIndex: 'suggestPrice',
                    align: 'center',
                    key: 'suggestPrice'
                }
            ]
        },
        {
            title: '预估效益空间（万元/周）',
            dataIndex: 'benefitSpace',
            align: 'center',
            key: 'benefitSpace'
        },
        {
            title: '操作',
            dataIndex: 'operate',
            align: 'center',
            key: 'operate'
        }
    ]
    const areaInfoTableData = ref([])
    const areaInfoTableLoading = ref(false)
    const areaInfoType = ref(null)
    let areaBasicInfo = null
    // 区域概况
    const loadAreaInfo = () => {
        if (areaInfoType.value === null) {
            areaInfoType.value = cementType.value[0] + '_' + packageType.value[0]
        }
        let useCenmentType = areaInfoType.value.split('_')[0]
        let usePkgType = areaInfoType.value.split('_')[1]
        let areaLevel = showAreaInfoLevel.value === 'city' ? 'region' : 'area'
        areaInfoTableLoading.value = true
        post('/dynamic-price/api/v1/realtime_price_optimize/initPriceAdjustData', {
            'areaName': showAreaInfoName.value,
            'areaLevel': areaLevel, //区县 area, 地级市 region
            'cementType': useCenmentType,
            'packType': usePkgType
        })
            .then(resp => {
                areaInfoTableData.value = JSON.parse(JSON.stringify(resp.data.priceOptimizeSuggestItems)).map(item => {
                    item.editing = false
                    item.originCurrentPrice = item.currentPrice
                    return item
                })
                areaBasicInfo = resp.data
            })
            .finally(() => {
                areaInfoTableLoading.value = false
            })
    }
    const updateAreaInfo = record => {
        areaInfoTableLoading.value = true
        post('/dynamic-price/api/v1/realtime_price_optimize/triggerPriceAdjust', {
            ...areaBasicInfo,
            changPriceItem: record
        })
            .then(resp => {
                areaInfoTableData.value = JSON.parse(JSON.stringify(resp.data.priceOptimizeSuggestItems)).map(item => {
                    item.editing = false
                    item.originCurrentPrice = item.currentPrice
                    return item
                })
                areaBasicInfo = resp.data
            })
            .finally(() => {
                areaInfoTableLoading.value = false
            })
    }
    const reloadAreaInfo = () => {
        loadAreaInfo()
    }
    // 弹窗 临近地市价差
    const areaInfoPriceDiffType = ref('')
    const areaInfoPriceDiffRawData = ref({})
    const areaInfoPriceDiffData = computed(() => {
        if (areaInfoPriceDiffType.value == null) {
            return []
        }
        return areaInfoPriceDiffRawData.value[areaInfoPriceDiffType.value] ?? []
    })
    const loadAreaInfoPriceDiff = () => {
        post('/dynamic-price/api/v2/timed_pricing_optimization/near_area_price_diff_search', {
            'cementVarity': config.cementType,
            'packageList': config.packageType,
            'code': '' + showAreaInfoCode.value
        })
            .then(resp => {
                areaInfoPriceDiffRawData.value = resp.data
            })
            .finally(() => {
                // 加载状态
            })
    }

    // 定价模拟
    // /dynamic-price/api/v1/scheme/detail/search
    // Pricing simulation
    const pricingSimulationTableColumns = [
        {
            title: '集团',
            dataIndex: 'enterpriseName',
            align: 'center',
            key: 'enterpriseName'
        },
        {
            title: '企业简称',
            dataIndex: 'enterpriseName',
            align: 'center',
            key: 'enterpriseName'
        },
        {
            title: '到位价（元/吨）',
            align: 'center',
            children: [
                {
                    title: '当前价',
                    dataIndex: 'currentPrice',
                    align: 'center',
                    key: 'currentPrice'
                },
                {
                    title: '建议价',
                    dataIndex: 'suggestPrice',
                    align: 'center',
                    key: 'suggestPrice'
                }
            ]
        },
        {
            title: '预估效益空间（万元/周）',
            dataIndex: 'benefitSpace',
            align: 'center',
            key: 'benefitSpace'
        },
        {
            title: '操作',
            dataIndex: 'operate',
            align: 'center',
            key: 'operate'
        }
    ]
    const pricingSimulationTableData = ref([])
    const pricingSimulationTableLoading = ref(false)

    // ####### 模拟优化
    const simulateModalVisible = ref(false)
    const simulateStep = ref(0)
    const simulateAreaSearchValue = ref('')
    const simulateTreeData = ref([])
    const simulateInitConditionForm = ref(null)

    const simulateForm = reactive({
        caseName: '',
        areas: [],
        maxPriceReductionAmount: 50,
        maxPriceIncreaseAmount: 50,
        marketShareFluctuationLowerLimitSign: '+',
        marketShareFluctuationLowerLimit: 0,
        marketShareFluctuationUpperLimitSign: '+',
        marketShareFluctuationUpperLimit: 0
    })

    const getTreeDataCode = data => {
        let code = []
        if (data && data.length > 0) {
            data.forEach(item => {
                if (item.type === '市') {
                    cityCodeAndNameMap[item.code] = item.name
                }
                code.push(item.code)
                code.push(...getTreeDataCode(item.children))
            })
        }
        return code
    }
    const cityCodeAndNameMap = {}
    const showSimulateModal = () => {
        // 加载数据
        // post('/dynamic-price/api/v1/scheme/province_city/TIMED', {}).then(resp => {
        //     simulateTreeData.value = resp.data
        // })
        //
        simulateTreeData.value = [
            {
                'id': 10000017,
                'name': '河北省',
                'type': '省',
                'parentId': 0,
                'disabled': false,
                'code': '130000',
                'longitude': 38.037707,
                'latitude': 114.530399,
                'location': {
                    'x': 38.037707,
                    'y': 114.530399,
                    'type': 'Point',
                    'coordinates': [38.037707, 114.530399]
                },
                'children': [
                    {
                        'id': 10000018,
                        'name': '唐山市',
                        'type': '市',
                        'parentId': 10000017,
                        'disabled': false,
                        'code': '130200',
                        'longitude': 118.180149,
                        'latitude': 39.63068,
                        'location': {
                            'x': 118.180149,
                            'y': 39.63068,
                            'type': 'Point',
                            'coordinates': [118.180149, 39.63068]
                        },
                        'children': []
                    }
                ]
            }
        ]

        simulateStep.value = 0
        // 重置表单
        simulateForm.caseName = dayjs().format('YYYYMMDD_HHmmss')
        simulateForm.areas = getTreeDataCode(simulateTreeData.value)
        simulateForm.maxPriceReductionAmount = 50
        simulateForm.maxPriceIncreaseAmount = 50
        simulateForm.marketShareFluctuationLowerLimitSign = '+'
        simulateForm.marketShareFluctuationLowerLimit = 0
        simulateForm.marketShareFluctuationUpperLimitSign = '+'
        simulateForm.marketShareFluctuationUpperLimit = 0
        simulateModalVisible.value = true
    }

    const handleSimulateNextStep = () => {
        if (simulateStep.value == 0) {
            simulateStep.value = 1
            handleSimulateStepChange(simulateStep.value)
        } else if (simulateStep.value == 1) {
            simulateStep.value = 2
            handleSimulateStepChange(simulateStep.value)
        }
    }

    const simulatePredictionTableLoading = ref(false)
    const simulatePredictionTableData = ref([])
    const simulatePredictionTableColumn = [
        {
            title: '省份',
            dataIndex: 'province',
            align: 'center',
            key: 'province',
            customCell: (record, rowIndex, column) => {
                return {
                    rowSpan: record.provinceRowSpan
                }
            }
        },
        {
            title: '总需求量(万吨)',
            dataIndex: 'provinceTotalDemand',
            align: 'center',
            key: 'provinceTotalDemand',
            customCell: (record, rowIndex, column) => {
                return {
                    rowSpan: record.provinceRowSpan
                }
            }
        },
        {
            title: '地级市',
            dataIndex: 'city',
            align: 'center',
            key: 'city'
        },
        {
            title: '地市需求量预测(万吨)',
            dataIndex: 'cityDemand',
            align: 'center',
            key: 'cityDemand'
        },
        {
            title: '地市需求量调整(万吨)',
            dataIndex: 'cityDemandChange',
            align: 'center',
            key: 'cityDemandChange'
        }
    ]
    const simulateCaseData = ref({})
    const simulateCaseLoading = ref(false)
    const handleSimulateStepChange = step => {
        if (step == 1) {
            // 进入需求与库存预测
            // 验证表单信息
            simulateInitConditionForm.value?.validate().then(resp => {
                // 根据选中得key获取对应的城市名
                let names = simulateForm.areas
                    .map(item => cityCodeAndNameMap[item])
                    .filter(item => item != null && item != undefined)
                if (names.length <= 0) {
                    message.error('未选择城市')
                    simulateStep.value = 0
                    return
                }
                simulatePredictionTableLoading.value = true
                // 加载数据
                return post('/dynamic-price/api/v1/scheme/demand_inventory', {
                    selectedCities: names
                })
                    .then(resp => {
                        let data = resp.data
                        let provinceList = {}
                        data.forEach(item => {
                            let value = provinceList[item.province] ?? 0
                            value = value + 1
                            provinceList[item.province] = value
                        })
                        for (let i = 0; i < data.length; i++) {
                            let province = data[i].province
                            let rowSpan = provinceList[province] ?? 0
                            delete provinceList[province]
                            data[i].provinceRowSpan = rowSpan
                        }
                        simulatePredictionTableData.value = data
                    })
                    .finally(() => {
                        simulatePredictionTableLoading.value = false
                    })
            })
        } else if (step == 2) {
            simulate()
        }
    }
    const simulateSelectProduct = ref(null)
    const simulateProductList = computed(() => {
        let productList = []
        simulateCaseData.value?.schemeDetailList?.forEach(item => {
            let product = item.product
            if (productList.indexOf(product) < 0) {
                productList.push(product)
            }
        })
        // 排序 ？
        return productList
    })

    const simulateCaseTableColumn = [
        {
            title: '序号',
            dataIndex: 'null',
            align: 'center',
            key: 'seqNum',
            customRender: ({ text, record, index, column }) => {
                return index + 1
            }
        },
        {
            title: '地级市',
            dataIndex: 'city',
            align: 'center',
            key: 'city',
            customCell: (record, rowIndex, column) => {
                return {
                    rowSpan: record.cityRowSpan
                }
            }
        },
        {
            title: '市场占有率(%)',
            align: 'center',
            children: [
                {
                    title: '模拟前',
                    dataIndex: 'beforeOccPred',
                    align: 'center',
                    key: 'beforeOccPred',
                    customCell: (record, rowIndex, column) => {
                        return {
                            rowSpan: record.cityRowSpan
                        }
                    }
                },
                {
                    title: '最优',
                    dataIndex: 'occPred',
                    align: 'center',
                    key: 'occPred',
                    customCell: (record, rowIndex, column) => {
                        return {
                            rowSpan: record.cityRowSpan
                        }
                    }
                }
            ]
        },
        {
            title: '到位价（元/吨）',
            align: 'center',
            children: [
                {
                    title: '模拟前',
                    dataIndex: 'beforeCityPrice',
                    align: 'center',
                    key: 'beforeCityPrice',
                    customCell: (record, rowIndex, column) => {
                        return {
                            rowSpan: record.cityRowSpan
                        }
                    }
                },
                {
                    title: '最优',
                    dataIndex: 'cityPrice',
                    align: 'center',
                    key: 'cityPrice',
                    customCell: (record, rowIndex, column) => {
                        return {
                            rowSpan: record.cityRowSpan
                        }
                    }
                }
            ]
        },
        {
            title: '预测销量（万吨）',
            align: 'center',
            children: [
                {
                    title: '模拟前',
                    dataIndex: 'beforeCityTotalSales',
                    align: 'center',
                    key: 'beforeCityTotalSales',
                    customCell: (record, rowIndex, column) => {
                        return {
                            rowSpan: record.cityRowSpan
                        }
                    }
                },
                {
                    title: '最优',
                    dataIndex: 'cityTotalSales',
                    align: 'center',
                    key: 'cityTotalSales',
                    customCell: (record, rowIndex, column) => {
                        return {
                            rowSpan: record.cityRowSpan
                        }
                    }
                }
            ]
        },
        {
            title: '效益空间(万元)',
            dataIndex: 'cityBenefitValue',
            align: 'center',
            key: 'cityBenefitValue',
            customCell: (record, rowIndex, column) => {
                return {
                    rowSpan: record.cityRowSpan
                }
            }
        },
        {
            title: '区县',
            dataIndex: 'county',
            align: 'center',
            key: 'county'
        },
        {
            title: '预测销量（万吨）',
            align: 'center',
            children: [
                {
                    title: '模拟前',
                    dataIndex: 'beforeAreaSales',
                    align: 'center',
                    key: 'beforeAreaSales',
                    customCell: (record, rowIndex, column) => {
                        return {
                            rowSpan: record.cityRowSpan
                        }
                    }
                },
                {
                    title: '最优',
                    dataIndex: 'areaSales',
                    align: 'center',
                    key: 'areaSales',
                    customCell: (record, rowIndex, column) => {
                        return {
                            rowSpan: record.cityRowSpan
                        }
                    }
                }
            ]
        },
        {
            title: '效益空间(万元)',
            dataIndex: 'beforeBenefitValue',
            align: 'center',
            key: 'beforeBenefitValue'
        },
        {
            title: '企业',
            dataIndex: 'companyName',
            align: 'center',
            key: 'companyName'
        },
        {
            title: '到位价（元/吨）',
            align: 'center',
            children: [
                {
                    title: '模拟前',
                    dataIndex: 'beforeAreaOptimalPrice',
                    align: 'center',
                    key: 'beforeAreaOptimalPrice',
                    customCell: (record, rowIndex, column) => {
                        return {
                            rowSpan: record.cityRowSpan
                        }
                    }
                },
                {
                    title: '最优',
                    dataIndex: 'areaOptimalPrice',
                    align: 'center',
                    key: 'areaOptimalPrice',
                    customCell: (record, rowIndex, column) => {
                        return {
                            rowSpan: record.cityRowSpan
                        }
                    }
                }
            ]
        }
    ]
    const simulateCaseTableData = computed(() => {
        let data = []
        let selectProduct = simulateSelectProduct.value
        simulateCaseData.value?.schemeDetailList?.forEach(item => {
            if (item.product !== simulateSelectProduct.value) {
                // 过滤条不是这个产品的
                return
            }
            // 过滤 ？
            data.push(item)
        })
        // 按照城市排序
        data.sort(function (a, b) {
            return b.city - a.city
        })
        // 统计各个市下面有多少县
        let cityCountMap = {}
        data.forEach(item => {
            let value = cityCountMap[item.city] ?? 0
            value = value + 1
            cityCountMap[item.city] = value
        })
        data.forEach(item => {
            let rowSpan = cityCountMap[item.city] ?? 0
            item.cityRowSpan = rowSpan
            delete cityCountMap[item.city]
        })
        return data
    })

    const simulate = () => {
        //
        let names = simulateForm.areas
            .map(item => cityCodeAndNameMap[item])
            .filter(item => item != null && item != undefined)
        if (names.length <= 0) {
            message.error('未选择城市')
            simulateStep.value = 0
            return
        }
        simulateCaseLoading.value = true
        let occDownthreshold = simulateForm.marketShareFluctuationLowerLimit
        if (simulateForm.marketShareFluctuationLowerLimitSign === '-') {
            occDownthreshold = occDownthreshold * -1
        }
        let occUpthreshold = simulateForm.marketShareFluctuationUpperLimit
        if (simulateForm.marketShareFluctuationUpperLimitSign === '-') {
            occUpthreshold = occUpthreshold * -1
        }
        post('/dynamic-price/api/v1/scheme/preview', {
            selectedCities: names,
            'downPrice': simulateForm.maxPriceReductionAmount,
            'upPrice': simulateForm.maxPriceIncreaseAmount,
            'occDownthreshold': occDownthreshold,
            'occUpthreshold': occUpthreshold,
            schemeDemandInventoryList: simulatePredictionTableData.value
        })
            .then(resp => {
                simulateCaseData.value = resp.data
            })
            .finally(() => {
                simulateCaseLoading.value = false
            })
    }

    const savingSimulate = ref(false)
    const saveSimulate = () => {
        // 保存模拟结果，生成方案
        let names = simulateForm.areas
            .map(item => cityCodeAndNameMap[item])
            .filter(item => item != null && item != undefined)
        if (names.length <= 0) {
            message.error('未选择城市')
            simulateStep.value = 0
            return
        }
        let occDownthreshold = simulateForm.marketShareFluctuationLowerLimit
        if (simulateForm.marketShareFluctuationLowerLimitSign === '-') {
            occDownthreshold = occDownthreshold * -1
        }
        let occUpthreshold = simulateForm.marketShareFluctuationUpperLimit
        if (simulateForm.marketShareFluctuationUpperLimitSign === '-') {
            occUpthreshold = occUpthreshold * -1
        }
        savingSimulate.value = true
        post('/dynamic-price/api/v1/scheme', {
            schemeName: simulateForm.caseName,
            schemeType: 'TIMED',
            selectedCities: names,
            'downPrice': simulateForm.maxPriceReductionAmount,
            'upPrice': simulateForm.maxPriceIncreaseAmount,
            'occDownthreshold': occDownthreshold,
            'occUpthreshold': occUpthreshold,
            schemeDemandInventoryList: simulatePredictionTableData.value,
            'totalBenefitValue': simulateCaseData.value.totalBenefitValue, // 总效益
            'totalSale': simulateCaseData.value.totalSale, //总销量
            'beforeTotalSale': simulateCaseData.value.beforeTotalSale, //总销量 模拟前
            schemeDetailList: simulateCaseData.value.schemeDetailList
        })
            .then(resp => {
                // 关闭弹窗
            })
            .finally(() => {
                savingSimulate.value = false
            })
    }
</script>
<style lang="less" scoped>
    .page_root {
        width: 100%;
        height: 100%;
        overflow: auto;
    }
    .page_root :deep(.@{ant-prefix}-spin-nested-loading),
    .page_root :deep(.@{ant-prefix}-spin-container) {
        height: 100%;
    }
    .page_root :deep(.@{ant-prefix}-spin-container .@{ant-prefix}-table-wrapper) {
        display: flex;
        flex-flow: column nowrap;
        justify-content: flex-start;
    }
    .page_root :deep(.@{ant-prefix}-table) {
        flex: auto;
        overflow: auto;
    }
    .table-moreBtn_down {
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
        width: 100px;
    }

    .table-moreBtn_menu :deep(.table-moreBtn_menu-item):hover {
        background: #ebf1ff;
    }

    /*  表格树结构样式处理，展开按钮层级增加*/
    :deep(.@{ant-prefix}-table-row-expand-icon) {
        z-index: 1;
    }
    /*  表格树结构 由于每个表格项采用自定义组件，使用绝对定位布局，开启树结构导致显示异常，暂时使用层级定位位置 */
    :deep(.@{ant-prefix}-table-row-level-1 .@{ant-prefix}-table-cell-with-append .cell-wrapper-left) {
        left: 15px !important;
        width: calc(100% - 15px);
    }
    :deep(.@{ant-prefix}-table-row-level-2 .@{ant-prefix}-table-cell-with-append .cell-wrapper-left) {
        left: 30px !important;
        width: calc(100% - 30px);
    }
    :deep(.@{ant-prefix}-table-row-level-3 .@{ant-prefix}-table-cell-with-append .cell-wrapper-left) {
        left: 45px !important;
        width: calc(100% - 45px);
    }
    :deep(.@{ant-prefix}-table-row-level-4 .@{ant-prefix}-table-cell-with-append .cell-wrapper-left) {
        left: 60px !important;
        width: calc(100% - 60px);
    }

    /* 穿梭框改变默认样式，为根据组件样式控制左右栏宽度。 */
    :deep(.@{ant-prefix}-transfer-list) {
        height: 100%;
        width: 50%;
    }

    .page-container {
        display: flex;
        flex-direction: column;
        height: 100%;
        width: 100%;
        .toolbar {
            height: 60px;
            width: 100%;
            flex-shrink: 0;
            background: #fff;
            display: flex;
            flex-direction: row;
            justify-content: space-between;
            align-items: center;
            padding: 0 24px;
        }
        .map-container {
            flex: 1;
            width: 100%;
            height: 100%;
        }
    }
</style>
